home *** CD-ROM | disk | FTP | other *** search
- //
- // Apple Macintosh DTS
- //
- // Sample code
- //
- // by Brian Bechtel, WWDTS
- //
- // File: CDROMDetection.c
- //
- // Copyright © 1998 Apple Computer, Inc.
- // All rights reserved.
- //
- // You may incorporate this sample code into your applications
- // without restriction, though the sample code has been provided
- // "AS IS" and the responsibility for its operation is 100%
- // yours. However, what you are not permitted to do is to
- // redistribute the source as "DTS Sample Code" after having made
- // changes. If you're going to re-distribute the source, we
- // require that you make it clear in the source that the code was
- // descended from DTS Sample Code, but that you've made
- // changes.
- //
-
- #include <TextUtils.h>
- #include <LowMem.h>
- #include <DriverGestalt.h>
- #include <Files.h>
- #include <Devices.h>
- #include <SCSI.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <SIOUX.h> // Metrowerks only
-
- // Be sure and put the #pragma options align=mac68k statement
- // around any structure definitions which require a particular
- // structure alignment; otherwise the compiler tries to word
- // align the definitions, and nothing works on the PowerPC side.
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=mac68k
- #endif
-
- struct DeviceIdentParam {
- QElemPtr qLink;
- short qType;
- short ioTrap;
- Ptr ioCmdAddr;
- IOCompletionUPP ioCompletion;
- OSErr ioResult;
- StringPtr ioNamePtr;
- short ioVRefNum;
- short ioCRefNum;
- short csCode;
- DeviceIdent deviceIdentification;
- short csParam[9];
- };
- typedef struct DeviceIdentParam DeviceIdentParam, *DeviceIdentParamPtr;
-
- #if PRAGMA_ALIGN_SUPPORTED
- #pragma options align=reset
- #endif
-
- // This declares in C a type called "CallForEveryDriveQueueElement"
- // which can then be declared as a variable in some other routine.
- // That routine can initialize the variable to the address of some
- // routine to call, and pass that as a parameter to CruiseDriveQueue.
- typedef pascal OSErr (*CallForEveryDriveQueueElement)(DrvQElPtr dqPtr);
- // to use the above declaration, you would have code such as this:
- // CallForEveryDriveQueueElement someCall = YourRoutineName;
- // CruiseDriveQueue(someCall);
- // where "YourRoutineName" is replaced by the name of a routine
- // which has been declared as follows:
- // pascal OSErr YourRoutineName(DrvQElPtr dqPtr);
- //
- // This is the declaration of the routine which cruises the drive
- // queue, calling the input parameter (a procedure) with each drive
- // queue element in the drive queue. It looks complicated, but
- // it winds up being much easier to use.
- pascal OSErr CruiseDriveQueue(CallForEveryDriveQueueElement theCall);
-
- void DetectCD(void);
- OSErr DeviceIdentification(
- StringPtr drvrNamePtr,
- DrvQElPtr dqPtr,
- DeviceIdent *d);
- pascal OSErr PrintDriverInformation(DrvQElPtr dqPtr);
- StringPtr DrvrRefToName(short refNum);
- OSErr DetermineUsingDriverGestalt(
- short driverRefNum,
- short driveNumber,
- OSType *deviceType);
-
- //-----------------------------------------------------------------
- // The main routine. Start here. We turn off the annoying
- // "Do you want to save this window?" option of Metrowerks
- // Standard Libraries
- //
- void main(void)
- {
- SIOUXSettings.asktosaveonclose = false; // Metrowerks only
-
- printf ("Sample showing how to detect CD-ROM drives\n\n");
-
- DetectCD();
- }
-
- //-----------------------------------------------------------------
- // This is the declaration of the routine which cruises the drive
- // queue, calling the input parameter (a procedure) with each drive
- // queue element in the drive queue. It looks complicated, but it
- // winds up being easy to use.
- //
- pascal OSErr CruiseDriveQueue(CallForEveryDriveQueueElement theCall)
- {
- register DrvQElPtr dqPtr;
- OSErr err;
-
- dqPtr = (DrvQElPtr) GetDrvQHdr()->qHead;
-
- while (dqPtr != NULL)
- {
- err = theCall(dqPtr);
- if (err)
- break;
- dqPtr = (DrvQEl *) dqPtr->qLink;
- }
- return (err);
- }
-
- //-----------------------------------------------------------------
- // This routine returns the device identification as documented
- // in Designing PCI Cards and Drivers
- //
- OSErr DeviceIdentification( StringPtr drvrNamePtr,
- DrvQElPtr dqPtr,
- DeviceIdent *d)
- {
- DeviceIdentParam pb = {0};
- OSErr err;
-
- pb.ioCompletion = nil;
- pb.ioNamePtr = drvrNamePtr;
- err = PBOpenSync((ParmBlkPtr)&pb);
-
- if (!err)
- {
- pb.ioVRefNum = dqPtr -> dQDrive;
- pb.ioCRefNum = dqPtr -> dQRefNum;
- pb.csCode = 120;
- err = PBStatusSync((ParmBlkPtr)&pb);
- }
- *d = pb.deviceIdentification;
- return err;
- }
-
- //-----------------------------------------------------------------
- // This routine just sets up a variable with the name of a routine
- // to call for every drive queue element, and then calls our
- // generic "scan the drive queue" routine. This will call the
- // routine we passed in for every drive queue element.
- // We tell the "CruiseDriveQueue" routine to call our
- // PrintDriverInformation routine for each entry in the drive queue.
- void DetectCD(void)
- {
- CallForEveryDriveQueueElement someCall = PrintDriverInformation;
- CruiseDriveQueue(someCall);
- }
-
- //-----------------------------------------------------------------
- // PrintDriverInformation prints information about the driver for
- // each Drive Queue Element we pass it. If the drive in question
- // passes tests to see if it's a CD-ROM drive, we print additional
- // information
- //
- pascal OSErr PrintDriverInformation(DrvQElPtr dqPtr)
- {
- StringPtr drvrNamePtr;
- OSType theDriveType;
- DeviceIdent d;
- OSErr err;
-
- // dqPtr->dQRefNum contains the driver reference number.
- // In order to display something to the user, we will get
- // the driver name by looking in the unit table (an array)
- // to find the driver name.
- drvrNamePtr = DrvrRefToName(dqPtr->dQRefNum);
-
- printf("DriverName: %.*s ", drvrNamePtr[0], &drvrNamePtr[1]);
- if ( EqualString(drvrNamePtr, "\p.AppleCD", false, true) )
- printf("(This is a CD-ROM drive.) ");
-
- err = DetermineUsingDriverGestalt(dqPtr->dQRefNum, dqPtr->dQDrive, &theDriveType);
- if (!err)
- {
- char c[5];
- BlockMoveData(&theDriveType, c, 4);
- c[4] = 0;
- printf("Driver Gestalt returned '%s'", c);
- }
-
- err = DeviceIdentification(drvrNamePtr, dqPtr, &d);
- if (!err)
- {
- printf("\nDevice reports that it is bus type %d, bus %d, target %d, partition/LUN %d.",
- d.diReserved, d.bus, d.targetID, d.LUN);
- }
- printf("\n");
- return noErr;
- }
-
- //-----------------------------------------------------------------
- // Lookup driver name from the unit table. The driver name starts
- // at 18 bytes into the driver itself. From the Unit Table entry
- // for this driver, get the name, but take into account whether it
- // is a handle based driver or a pointer based driver.
- //
- StringPtr DrvrRefToName(short refNum)
- {
- AuxDCEHandle* UTable = (AuxDCEHandle*) LMGetUTableBase();
- DCtlPtr dctl;
- Ptr p;
- static StringPtr driverName;
-
- if ( refNum == 0 )
- {
- driverName = "\p<none>";
- }
- else
- {
- dctl = (DCtlPtr) *UTable[~refNum];
- p = dctl->dCtlDriver;
-
- // a RAMbased driver is handle based, a ROMbased driver
- // is pointer based. If it's a handle based driver, we
- // need one more level of indirection. The following
- // test provides that indirection if necessary.
- if( dctl->dCtlFlags & dRAMBasedMask)
- p = (void*) *p;
-
- if ( p != nil )
- driverName = (void *)(p+18);
- else
- driverName = "\p-Purged-";
- }
- return ( driverName);
- }
-
- //-----------------------------------------------------------------
- // Call the driver using the DriverGestalt status code. The result
- // tells us if this driver is a CD-ROM
- //
- OSErr DetermineUsingDriverGestalt(short driverRefNum,
- short driveNumber,
- OSType *deviceType)
- {
- DriverGestaltParam pb;
- OSErr err;
-
- pb.ioVRefNum = driveNumber;
- pb.ioCRefNum = driverRefNum;
- pb.csCode = kDriverGestaltCode;
- pb.driverGestaltSelector = kdgDeviceType;
-
- err = PBStatusSync((ParmBlkPtr) &pb);
-
- if (!err)
- {
- *deviceType = pb.driverGestaltResponse;
- }
- return (err);
- }
-
-